/**
 * Created by chenxiaoyu on 2018/8/28
 * Email 1524904743@qq.com
 */
var test= angular.module('testModule',['ui.router']);

// console.log(ject.has());
test.factory('testTool', function () {
    return {
        name: '张三'
    }
})
test.controller('testCtrl', [
    '$scope',
    'CON',
    'prod',
    'dtUtils',
    'utils',
    'prodbak',
    'setRouter',
    function ($scope, con, prod, dtUtils, utils, prodbak, setRouter) {
        $scope.test= con.system;
        $scope.version= con.version;
        $scope.info= prod;
        $scope.dataInfo= dtUtils.info;
        $scope.setVal= dtUtils.setVal;
        var sum= utils.getSum(12,32,"wq",344,434);
        window.addEventListener('message', function (event) {
            console.log(event, '===============')
        })
        $scope.$evalAsync(function () {     // 异步调用，类似settTmeout
            // alert(234);
        });
        $scope.$evalAsync(function () {
            alert(345);
        });
        // alert(567);
        console.log(prodbak.add(10, 4));
        var arr= [2,3,4,2,3,5,6,7,1,'2','1','2'];
        var newArr= utils.unique(arr);
        console.log(newArr);
        console.log(setRouter.test)
        var arr1= [12,33,434,43,3,5,6,7,1,'22','13','2'];
        console.log(arr1);
        utils.byOrder(arr1, 1);
        console.log(arr1)
    }
])


/*
test.controller('testCtrl2', [
    '$scope',
    'dtUtils',
    function ($scope, dtUtils) {
        // var obj= angular.injector(["$scope"]);
        // console.log(obj);
    }
])
*/

test.constant('CON', {
    system: '中行智能客服',
    version: '1.1.12'
})

test.provider('prod', {
    $get: function (CON) {
        return CON.system + '：是利用人工智能机器人实现的自助式客服服务';
    }
})

test.service('dtUtils', [
    function () {
        var that= this;
        that.info= "这是单列的SERVICE，主要用于数据的共享。";
        that.data= "共享数据";
        this.setVal= function (val) {
            that.data= val;
        }
    }
])

test.factory('utils', [
    function () {
        return {
            getSum: function () {   // 求和
                var sum= 0;
                for(var i=0; i<arguments.length; i++){
                    var cot= arguments[i];
                    if (!isNaN(Number(cot))){
                        sum+= Number(cot);
                    }
                }
                return sum;
            },
            unique: function (arr) {    // 数组去重
                if (angular.isArray(arr)){
                    var tempArr= [];
                    angular.forEach(arr, function (item) {
                        if (tempArr.indexOf(item) == -1){
                            tempArr.push(item);
                        }
                    })
                    return tempArr;
                }
            },
            byOrder: function (arr, s) {    // 数组排序，s表示排序方式，<=0降序，>0升序
                if (angular.isArray(arr)){
                    arr.sort(function (a, b) {
                        if (arguments.length >= 2 && !isNaN(Number(s)) && Number(s) > 0) {
                            return a - b;   // 升序
                        }
                        if (arguments.length >= 2 && !isNaN(Number(s)) && Number(s) <= 0){
                            return b - a; // 降序
                        }
                        return 0;
                    })
                }
            }
        }
    }
])

test.directive('pro', [function () {
    return {
        restrict: 'AECM',
        scope: false,
        // template: '<div><button>点我吧</button></div>',
        controller: function ($scope) {
            $scope.publicArr= [];
            this.getSum= function (a, b) {
                return a+b;
            }
            this.addSpeed= function () {
                $scope.publicArr.push('speed');
            }
            this.addStrong= function () {
                $scope.publicArr.push('strong');
            }
        }
    }
}])
test.directive('drv', ['$templateCache', function ($templateCache) {
    return {
        restrict: 'AECM', //默认A， 指令的应用形式，元素、属性、css类以及注释
        priority: 0,    //默认0， 指令的执行顺序，数值越大优先级越高
        scope: false,   //默认false, 定义指令的作用域，false与controller共用$scope,true继承controller的$scope独立新建的scope,{}新建的独立scope
        replace: false,  // 默认false，是否隐藏渲染后的指令标签名
        // 指令模板，可以使html代码，也可以是返回html的函数，函数接收2个参数：element和attr
        template: '<div><span ng-transclude></span><a href="http://www.baidu.com" target=_blank style="color: red;">点击跳转百度搜索</a></div>',
        //templateUrl: '../index.html',   //指令引用外部模板url，也可以是返回模板url的函数，函数接收2个参数：element和attr
        //template: $templateCache.get('./client/components/test/tpl/hello.html'),  // 从$templateCache中读取模板缓存，可以解决同时加载大量模板拖慢网站的问题，这里的模板缓存需要在run方法中一次性存入
        transclude: true,   // 指令元素内部的内容是否显示，注意还需要在指令模板中用ng-transclude标志显示的位置，
        require: '?^pro',   // 指定该指令所依赖的指令名称，？表示若找不到所依赖的指令控制器，则返回null,^表示当前元素找不到，就到父元素中去找
        /*
        * 定义指令控制器，向外提供一组公共的方法，共其他指令调用，这里也可以注入其他的服务
        * */
        controller: function($scope, $element, $attrs){
            this.public= function () {
                console.log("这是公共的方法");
            }
        },
        /*link函数负责在模型和视图之间进行动态关联,每个指令实例化都会执行一次，
        * scope: 当前指令的作用域
        * elem: 当前指令的DOM对象
        * attrs: 当前指令的属性集合对象
        * ctrl：当前指令所依赖的指令的controller，这里的值可能为null
        * */
        link: function (scope,elem,attrs,proCtrl) {
            // console.log($templateCache.get('./client/components/test/tpl/hello.html'));
            proCtrl.addSpeed();
            // console.log(scope.publicArr);
        }
    }
}])
// 自定义过滤器
test.filter('toUpCase', [function () {
    return function (msg, t, s) {      // 第一个参数为过滤源数据，后面的都为过滤器自身的参数
        if (typeof msg !== 'string'){
            throw '该过滤器只能用于字符串'
        } else {
            if (!!t && t === 1){
                msg= msg.toUpperCase();
            } else {
                msg= msg.toLowerCase();
            }
            if (!!s && s===1){
                var arr= msg.split("").sort();
                msg= arr.join("");
            }
            return msg;
        }
    }
}])
/*
* 全局http拦截器：
* 拦截器的创建主要依赖于$httpProvider，在$httpProvider中有一个interceptors数组，拦截器就是注册在该数组中的服务工厂方法
* 创建拦截器主要有以下2步：
* 1、定义拦截器的实现factory方法；
* 2、将该factory注册到interceptors数组中
* */
// 定义拦截器的实现factory方法，该方法形式是固定的
test.factory('httpInterceptor', [
    '$q',
    function ($q) {
        return {
            request: function (httpConfig) {
                return httpConfig || $q.when(httpConfig);
            },
            requestError: function (rejection) {
                return $q.reject(rejection);
            },
            response: function (resp) {
                return resp || $q.when(resp);
            },
            responseError: function (rejection) {
                return $q.reject(rejection);
            }
        }
    }
])

/*
* provider
* provider是angularjs的核心服务配方，其他的几种服务：Value, Factory, Service and Constant都是基于provider包装实现的
* 关于provider的用法需要注意以下几点：
* 1、虽然provider的功能最全，但是由于其他的已封装专用服务的存在，因此一般情况下都不建议直接使用provider。
* 2、provider内部是一个$get方法，这个方法必须有返回值，且该方法的参数只能是注入的服务。
* 3、$get方法的返回值可以是方法、对象或字符串。
* 4、provider可以是唯一可以在config方法中注入的服务，因此常用来做全局化的设置。
* 5、可以利用provider来动态加载路由
* */
test.provider('prodbak', {
    $get: ['$http', 'CON', function ($http, con) {
        return {
            add: function (x, y) {
                return x + y;
            }
        }
    }]
})

// provider动态加载路由实例
test.constant('URL', {  // 路由数据对象
    'test': {
        url: '/test',
        templateUrl: './client/components/test/test.html'
    }
})
// 根据路由数据对象拼装路由
test.provider('setRouter', ['$stateProvider', function($stateProvider){
    this.$get= ['URL', '$state', function (URL, $state) {
        return {
            set: function () {
                angular.forEach(URL, function (val, key) {
                    if (!$state.get(key)){
                        $stateProvider.state(key, val);
                    }
                })
            }
        };
    }]
}])
/*
* 补充知识点：
* 1、原生js自定义事件监听
* 2、angularjs拦截器
* 3、angularjs过滤器
* 4、angularjs--provider
* 5、数组的常规操作：排序、去重、截取和拷贝
* 6、gulp自动化构建
* 7、angularjs内部通信机制
* 8、常用的指令与服务
* 9、原生jsDOM操作
* */

/*
* 事件广播机制一：
*   原生js实现的常规事件广播监听
* */
// 创建事件对象--老版本
var evt= document.createEvent('HTMLEvents');
evt.initEvent('myself', false, false);
// 添加事件传输的数据
evt.data= {
    name: 'zhangsan',
    age: 23
}
// 触发事件
// window.dispatchEvent('myself');
/**********以上自定义事件的方式已弃用***********/
// 创建事件对象--新版本
// 不需要传递数据
var evts= new Event('sends');
window.dispatchEvent(evts);
// 需要传递数据的用下面的方式
var evts_= new CustomEvent('sendData', {data:"这是传递的数据"});
window.dispatchEvent(evts_);

// 自定义事件的监听器
window.addEventListener('myself', function (event) {
    console.log(event.data);
})
window.addEventListener('sends', function (e) {
    console.log(e.data);
})
window.addEventListener('sendData', function (e) {
    console.log(e.data);
})

// 涉及到iframe跨域事件监听，可以用HTML5提供的postMessage
// 发送跨域事件
// $('#make-tab').find('iframe')[0].contentWindow.postMessage('message', 'http://localhost:8000');
// 监听跨域事件
/*
window.addEventListener('message', function (event) {
    console.log(event.data)
})
*/



